package com.baoyouqun.service.impl;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.func.Func0;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baoyouqun.base.utils.ConvertUtils;
import com.baoyouqun.domain.CreateCmd.SystemConfigCreateCmd;
import com.baoyouqun.domain.Enum.SystemConfigType;
import com.baoyouqun.domain.Query.SystemConfigQuery;
import com.baoyouqun.domain.UpdateCmd.SystemConfigUpdateCmd;
import com.baoyouqun.domain.VO.*;
import com.baoyouqun.entity.SystemConfig;
import com.baoyouqun.mapper.SystemConfigMapper;
import com.baoyouqun.service.SystemConfigService;
import jakarta.annotation.Resource;
import org.apache.poi.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


@Service
public class SystemConfigServiceImpl extends ServiceImpl<SystemConfigMapper, SystemConfig> implements SystemConfigService {
    private static final Logger log = LoggerFactory.getLogger(SystemConfigServiceImpl.class);

    // 定义标签缓存：key为标签名（如"互联网/AI"），value为子标签列表
    private final Cache<String, List<String>> tagCache = CacheUtil.newTimedCache(3600000);

    @Resource
    private SystemConfigMapper systemConfigMapper;

    /**
     * 查询短信模板配置：从info8解析JSON
     */
    @Override
    public SmsTemplateDTO getSmsTemplate() {
        // 从数据库获取SMS_TEMPLATE类型的配置
        SystemConfig config = getByType(SystemConfigType.SMS_TEMPLATE.getCode());
        // 转换为DTO返回
        return SmsTemplateDTO.fromSystemConfig(config);
    }

    /**
     * 更新短信模板配置：将DTO转JSON存入info8
     */
    @Override
    public void updateSmsTemplate(SmsTemplateDTO dto) {
        // 获取现有配置（不存在则自动初始化，复用原有getByType逻辑）
        SystemConfig config = getByType(SystemConfigType.SMS_TEMPLATE.getCode());
        // 将DTO的模板列表转为JSON，存入info8
        dto.toSystemConfig(config);
        // 保存更新
        systemConfigMapper.updateById(config);
    }

    @Override
    public SingleResponse<SystemConfigVO> create(SystemConfigCreateCmd cmd) {
        SystemConfig entity = ConvertUtils.copyBean(cmd, SystemConfig.class);
        boolean result = save(entity);
        if (!result) {
            return SingleResponse.buildFailure("100101", "创建失败");
        }

        SystemConfigVO vo = ConvertUtils.copyBean(entity, SystemConfigVO.class);
        return SingleResponse.of(vo);
    }

    @Override
    public Response update(SystemConfigUpdateCmd cmd) {
        if (Objects.isNull(cmd)) {
            return Response.buildFailure("100301", "参数不能为空");
        }
        if (StringUtil.isBlank(cmd.getId())) {
            return Response.buildFailure("100302", "ID不能为空");
        }
        SystemConfig oldEntity = getById(cmd.getId());
        if (Objects.isNull(oldEntity)) {
            return Response.buildFailure("100303", "未查询到此数据");
        }
        oldEntity = ConvertUtils.copyBean(cmd, SystemConfig.class);
        boolean result = updateById(oldEntity);
        if (result) {
            return Response.buildSuccess();
        } else {
            return Response.buildFailure("100304", "更新失败");
        }
    }

    @Override
    public SystemConfigVO selectById(String id) {
        SystemConfig entity = systemConfigMapper.selectById(id);
        return ConvertUtils.copyBean(entity, SystemConfigVO.class);
    }

    @Override
    public IPage<SystemConfigVO> pageVo(SystemConfigQuery query) {
        IPage<SystemConfig> page = new Page<>(query.getCurrent(), query.getSize());
        page = page(page, new LambdaQueryWrapper<SystemConfig>());
        Page<SystemConfigVO> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        List<SystemConfigVO> records = ConvertUtils.copyBeanList(page.getRecords(), SystemConfigVO.class);
        voPage.setRecords(records);
        return voPage;
    }

    // ------------------------------ 查询方法 ------------------------------
    @Override
    public BackgroundRolePermissionDTO getBackgroundRolePermission() {
        SystemConfig config = getByType(SystemConfigType.BACKGROUND_ROLE_PERMISSION.getCode());
        return new BackgroundRolePermissionDTO();
    }

    @Override
    public InviteFriendDTO getInviteFriend() {
        SystemConfig config = getByType(SystemConfigType.INVITE_FRIEND.getCode());
        return InviteFriendDTO.fromSystemConfig(config);
    }

    @Override
    public AddFriendDTO getAddFriend() {
        SystemConfig config = getByType(SystemConfigType.ADD_FRIEND.getCode());
        return AddFriendDTO.fromSystemConfig(config);
    }

    @Override
    public PublishPostDTO getPublishPost() {
        SystemConfig config = getByType(SystemConfigType.PUBLISH_POST.getCode());
        return PublishPostDTO.fromSystemConfig(config);
    }

    @Override
    public NonLeopardVisitDTO getNonLeopardVisit() {
        SystemConfig config = getByType(SystemConfigType.NON_LEOPARD_USER_VISIT_DURATION.getCode());
        return NonLeopardVisitDTO.fromSystemConfig(config);
    }

    @Override
    public VipMemberDTO getVipMember() {
        SystemConfig config = getByType(SystemConfigType.VIP_MEMBER.getCode());
        return VipMemberDTO.fromSystemConfig(config);
    }

    @Override
    public VirtualCallDTO getVirtualCall() {
        SystemConfig config = getByType(SystemConfigType.VIRTUAL_CALL.getCode());
        return VirtualCallDTO.fromSystemConfig(config);
    }

    @Override
    public PostTypeDTO getPostType() {
        SystemConfig config = getByType(SystemConfigType.POST_TYPE.getCode());
        return PostTypeDTO.fromSystemConfig(config);
    }

    @Override
    public LeopardNumberRuleDTO getLeopardNumberRule() {
        SystemConfig config = getByType(SystemConfigType.LEOPARD_NUMBER_RULE.getCode());
        return LeopardNumberRuleDTO.fromSystemConfig(config);
    }

    // ------------------------------ 协议查询方法 ------------------------------
    @Override
    public UserAgreementDTO getUserAgreement() {
        SystemConfig config = getByType(SystemConfigType.USER_AGREEMENT.getCode());
        return UserAgreementDTO.fromSystemConfig(config);
    }

    @Override
    public PrivacyPolicyDTO getPrivacyPolicy() {
        SystemConfig config = getByType(SystemConfigType.PRIVACY_POLICY.getCode());
        return PrivacyPolicyDTO.fromSystemConfig(config);
    }

    @Override
    public ServiceTermsDTO getServiceTerms() {
        SystemConfig config = getByType(SystemConfigType.SERVICE_TERMS.getCode());
        return ServiceTermsDTO.fromSystemConfig(config);
    }

    @Override
    public ServiceTermsDTO getRegistrationBenefitss() {
        SystemConfig config = getByType(SystemConfigType.REGISTRATION_BENEFITS.getCode());
        return ServiceTermsDTO.fromSystemConfig(config);
    }

    @Override
    public void updateRegistrationBenefitss(ServiceTermsDTO dto) {
        SystemConfig config = getByType(SystemConfigType.REGISTRATION_BENEFITS.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public ServiceTermsDTO getCompanyPhilosophy() {
        SystemConfig config = getByType(SystemConfigType.COMPANY_PHILOSOPHY.getCode());
        return ServiceTermsDTO.fromSystemConfig(config);
    }

    @Override
    public void updateCompanyPhilosophy(ServiceTermsDTO dto) {
        SystemConfig config = getByType(SystemConfigType.COMPANY_PHILOSOPHY.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }


    // ------------------------------ 更新方法 ------------------------------
    @Override
    public void updateBackgroundRolePermission(BackgroundRolePermissionDTO dto) {
        SystemConfig config = getByType(SystemConfigType.BACKGROUND_ROLE_PERMISSION.getCode());
        baseMapper.updateById(config);
    }

    @Override
    public void updateInviteFriend(InviteFriendDTO dto) {
        SystemConfig config = getByType(SystemConfigType.INVITE_FRIEND.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public void updateAddFriend(AddFriendDTO dto) {
        SystemConfig config = getByType(SystemConfigType.ADD_FRIEND.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public void updatePublishPost(PublishPostDTO dto) {
        SystemConfig config = getByType(SystemConfigType.PUBLISH_POST.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public void updateNonLeopardVisit(NonLeopardVisitDTO dto) {
        SystemConfig config = getByType(SystemConfigType.NON_LEOPARD_USER_VISIT_DURATION.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public void updateVipMember(VipMemberDTO dto) {
        SystemConfig config = getByType(SystemConfigType.VIP_MEMBER.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public void updateVirtualCall(VirtualCallDTO dto) {
        SystemConfig config = getByType(SystemConfigType.VIRTUAL_CALL.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public void updatePostType(PostTypeDTO dto) {
        SystemConfig config = getByType(SystemConfigType.POST_TYPE.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public void updateLeopardNumberRule(LeopardNumberRuleDTO dto) {
        SystemConfig config = getByType(SystemConfigType.LEOPARD_NUMBER_RULE.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    // ------------------------------ 协议更新方法 ------------------------------
    @Override
    public void updateUserAgreement(UserAgreementDTO dto) {
        SystemConfig config = getByType(SystemConfigType.USER_AGREEMENT.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public void updatePrivacyPolicy(PrivacyPolicyDTO dto) {
        SystemConfig config = getByType(SystemConfigType.PRIVACY_POLICY.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    @Override
    public void updateServiceTerms(ServiceTermsDTO dto) {
        SystemConfig config = getByType(SystemConfigType.SERVICE_TERMS.getCode());
        dto.toSystemConfig(config);
        baseMapper.updateById(config);
    }

    // ------------------------------ 通用方法 ------------------------------
    private SystemConfig getByType(String configType) {
        SystemConfigType type = SystemConfigType.getByCode(configType);
        if (type == null) {
            throw new IllegalArgumentException("无效的配置类型: " + configType);
        }
        SystemConfig config = baseMapper.selectOne(
                new LambdaQueryWrapper<SystemConfig>()
                        .eq(SystemConfig::getConfigType, configType)
        );
        if (config == null) {
            // 不存在则初始化一个
            config = new SystemConfig();
            config.setConfigType(type);
            config.setConfigName(type.getDesc());
            config.setCreateTime(LocalDateTime.now());
            baseMapper.insert(config);
        }
        return config;
    }

    @Override
    public List<String> getTagWithOneLevelChildren(String tag) {
        // 从缓存获取，若不存在则执行lambda表达式查询数据库并缓存
        return tagCache.get(tag, true, (Func0<List<String>>) () -> {
            // 原逻辑：查询数据库并解析标签
            SystemConfig config = getByType(SystemConfigType.POST_TYPE.getCode());
            PostTypeDTO postType = PostTypeDTO.fromSystemConfig(config); // 解析BLOB为标签树
            return collectChildrenTags(postType, tag); // 递归收集子标签
        });
    }

    private List<String> collectChildrenTags(PostTypeDTO root, String tag) {
        log.warn("star+=====" + LocalDateTime.now());
        List<String> resultList = new ArrayList<>();
        if (tag == null) { // 防御空输入
            return resultList;
        }

        // 1. 使用传入的root对象的顶层分类列表（修复：移除重复获取逻辑）
        List<PostTypeDTO.PostTypeSonDTO> topLevelList = root.getList();
        if (CollUtil.isEmpty(topLevelList)) {
            return resultList;
        }

        // 2. 递归查找所有层级中，title等于tag的目标节点
        PostTypeDTO.PostTypeSonDTO targetNode = findTargetNode(topLevelList, tag);
        if (targetNode == null) { // 标签不存在于任何层级
            return resultList;
        }

        // 3. 从目标节点递归收集：自身标签 + 所有子孙标签
        collectTags(targetNode, resultList);

        log.warn("end+=====" + LocalDateTime.now());
        return resultList;
    }

    /**
     * 递归查找所有层级中，title等于目标tag的节点
     */
    private PostTypeDTO.PostTypeSonDTO findTargetNode(List<PostTypeDTO.PostTypeSonDTO> nodeList, String tag) {
        if (CollUtil.isEmpty(nodeList)) {
            return null;
        }

        for (PostTypeDTO.PostTypeSonDTO node : nodeList) {
            if (node == null) {
                continue;
            }

            // 若当前节点的title匹配tag，直接返回该节点
            String currentTitle = node.getTitle();
            if (tag.equals(currentTitle)) {
                return node;
            }

            // 若当前节点有子节点，递归查找子节点层级
            List<PostTypeDTO.PostTypeSonDTO> children = node.getList();
            PostTypeDTO.PostTypeSonDTO childTarget = findTargetNode(children, tag);
            if (childTarget != null) { // 子层级找到目标节点，直接返回
                return childTarget;
            }
        }

        return null; // 所有层级均未找到
    }

    /**
     * 递归收集目标节点的「自身标签 + 所有子孙标签」
     */
    private void collectTags(PostTypeDTO.PostTypeSonDTO node, List<String> resultList) {
        if (node == null) {
            return;
        }

        // 1. 添加当前节点的标签（过滤空title）
        String currentTitle = node.getTitle();
        if (currentTitle != null) {
            resultList.add(currentTitle);
        }

        // 2. 递归收集所有子节点的标签
        List<PostTypeDTO.PostTypeSonDTO> children = node.getList();
        if (CollUtil.isEmpty(children)) {
            return; // 无子孙节点，递归终止
        }

        for (PostTypeDTO.PostTypeSonDTO child : children) {
            collectTags(child, resultList);
        }
    }

}